package org.despair2D.ui 
{
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.despair2D.control.TouchManager;
	import org.despair2D.control.ZMouseEvent;
	import org.despair2D.core.ns_despair;
	import org.despair2D.debug.Logger;
	import org.despair2D.model.RangeProperty;
	import org.despair2D.ui.core.IComponent;
	import org.despair2D.ui.core.UIManager;
	import org.despair2D.ui.puppet.NineScalePuppet;
	use namespace ns_despair;
	
public class BothwayScroller 
{
	
	public function BothwayScroller( target:IComponent, maskWidth:Number, maskHeight:Number, contentWidth:Number, contentHeight:Number) 
	{
		var global:Point
		
		if (m_maskWidth <= 0 && m_maskHeight <= 0) 
		{
			Logger.reportError(this, 'constructor', '视域尺寸不可为负 !!')
		}
		
		m_target           =  target
		global             =  m_target.globalPos
		m_targetRect       =  new Rectangle(global.x, global.y, maskWidth, maskHeight)
		m_scrollRect       =  new Rectangle(0, 0, maskWidth, maskHeight)
		m_maskWidth        =  maskWidth
		m_maskHeight       =  maskHeight
		m_horizontalRange  =  new RangeProperty(0, 0, contentWidth - maskWidth > 0 ? contentWidth - maskWidth : 0)
		m_verticalRange    =  new RangeProperty(0, 0, contentHeight - maskHeight > 0 ? contentHeight - maskHeight : 0)
		
		m_horizontalRange.binding(__onHorizontalChange, true)
		m_verticalRange.binding(__onVerticalChange, true)
		
		// 触滑更新
		TouchManager.getInstance().addEventListener(ZMouseEvent.MOUSE_PRESS, __onStart, false, 8000)
	}
	
	
	/** 内部宽度 **/
	public function get contentWidth() : Number { return m_horizontalRange.maximum }
	public function set contentWidth( v:Number ) : void { m_horizontalRange.maximum = v - m_maskWidth > 0 ? v - m_maskWidth : 0 }
	
	/** 内部高度 **/
	public function get contentHeight() : Number { return m_verticalRange.maximum }
	public function set contentHeight( v:Number ) : void { m_verticalRange.maximum = v - m_maskHeight > 0 ? v - m_maskHeight : 0 }
	
	/** 水平范围属性(可使用其手动改变视域位置) **/
	public function get horizontalRange() : RangeProperty { return m_horizontalRange }
	
	/** 垂直范围属性(可使用其手动改变视域位置) **/
	public function get verticalRange() : RangeProperty { return m_verticalRange }
	
	/** 触滑位差，对内部组件失效的界限值 **/
	public function get boundary() : Number { return m_boundary }
	public function set boundary( v:Number ) : void { m_boundary = v }
	
	/** 是否锁定 **/
	public function get locked() : Boolean { return m_locked }
	public function set locked( b:Boolean ) : void 
	{ 
		m_locked = b
		this.__onRelease(null)
	}
	
	
	/**
	 * 获取水平滑块
	 * @param	thumbDataName
	 * @param	length
	 * @param	width
	 */
	public function getHorizontalThumb( thumbDataName:String, length:Number, width:Number = -1 ) : Fusion
	{
		if (!m_horizontalThumb)
		{
			m_horizontalThumb = new Fusion()
			m_horizontalThumb.spaceWidth = length
			m_horizontalThumb.spaceHeight = width
			m_horizontalElement = new NineScalePuppet(thumbDataName, length * m_verticalRange.ratio, width)
			m_horizontalThumb.addElement(m_horizontalElement)
			this.__onHorizontalChange()
		}
		return m_horizontalThumb
	}
	
	/**
	 * 获取垂直滑块
	 * @param	thumbDataName
	 * @param	length
	 * @param	width
	 */
	public function getVerticalThumb( thumbDataName:String, length:Number, width:Number = -1 ) : Fusion
	{
		if (!m_verticalThumb)
		{
			m_verticalThumb = new Fusion()
			m_verticalThumb.spaceWidth = width
			m_verticalThumb.spaceHeight = length
			m_verticalElement = new NineScalePuppet(thumbDataName, width, length * m_verticalRange.ratio)
			m_verticalThumb.addElement(m_verticalElement)
			this.__onVerticalChange()
		}
		return m_verticalThumb
	}
	
	/**
	 * 释放
	 */
	public function dispose() : void
	{
		TouchManager.getInstance().removeEventListener(ZMouseEvent.MOUSE_PRESS, __onStart)
		if (m_scrolling)
		{
			TouchManager.getInstance().removeEventListener(ZMouseEvent.MOUSE_MOVE,    __onScroll)
			TouchManager.getInstance().removeEventListener(ZMouseEvent.MOUSE_RELEASE, __onRelease)
			
			if (m_isStopPropagation)
			{
				UIManager.m_interactive = true
				UIManager.reset()
			}
		}
		
		m_target.displayObject.scrollRect = m_targetRect = m_scrollRect = null
		m_target.kill()
		m_target = null
		m_horizontalRange.dispose()
		m_verticalRange.dispose()
		m_horizontalRange = m_verticalRange = null
		m_horizontalThumb = m_verticalThumb = null
		m_horizontalElement = m_verticalElement = null
	}
	
	
	ns_despair function __onStart( e:ZMouseEvent ) : void
	{
		// 内部宽高不足或被锁定，跳过检测
		if((m_horizontalRange.maximum < m_maskWidth && m_verticalRange.maximum < m_maskHeight) || m_locked)
		{
			return
		}
		
		m_oldX = m_startX = TouchManager.getInstance().touchX
		m_oldY = m_startY = TouchManager.getInstance().touchY
		
		if (m_targetRect.contains(m_startX, m_startY))
		{
			//trace('scroll')
			TouchManager.getInstance().addEventListener(ZMouseEvent.MOUSE_MOVE,    __onScroll,  false, 8000)
			TouchManager.getInstance().addEventListener(ZMouseEvent.MOUSE_RELEASE, __onRelease)
			m_scrolling = true
		}
	}
	
	ns_despair function __onScroll( e:ZMouseEvent ) : void
	{
		var mouseX:Number, mouseY:Number
		
		mouseX = TouchManager.getInstance().touchX
		mouseY = TouchManager.getInstance().touchY
		
		// 当发生触摸位移差达到一定程序时，屏蔽组件
		if (!m_isStopPropagation && ((Math.abs(m_oldX - m_startX) > m_boundary || Math.abs(m_oldY - m_startY) > m_boundary)))
		{
			m_isStopPropagation = true
			UIManager.m_interactive = false
		}
		
		m_horizontalRange.value -= mouseX - m_oldX
		m_verticalRange.value -= mouseY - m_oldY
		m_oldX = mouseX
		m_oldY = mouseY
	}
	
	ns_despair function __onRelease( e:ZMouseEvent ) : void
	{
		if (m_scrolling)
		{
			TouchManager.getInstance().removeEventListener(ZMouseEvent.MOUSE_MOVE,    __onScroll)
			TouchManager.getInstance().removeEventListener(ZMouseEvent.MOUSE_RELEASE, __onRelease)
			m_scrolling = false
		}
		
		if (m_isStopPropagation)
		{
			m_isStopPropagation = false
			UIManager.m_interactive = true
			UIManager.reset()
		}
	}
	
	ns_despair function __onHorizontalChange() : void
	{
		m_scrollRect.x                     =  m_horizontalRange.value
		m_target.displayObject.scrollRect  =  m_scrollRect
		if (m_horizontalThumb)
		{
			m_horizontalElement.width  =  m_horizontalThumb.spaceWidth * m_maskWidth / (m_maskWidth + m_horizontalRange.maximum)
			m_horizontalElement.x      =  (m_horizontalThumb.spaceWidth - m_horizontalElement.width) * m_horizontalRange.ratio
		}
	}
	
	ns_despair function __onVerticalChange() : void
	{
		m_scrollRect.y                     =  m_verticalRange.value
		m_target.displayObject.scrollRect  =  m_scrollRect
		if (m_verticalThumb)
		{
			m_verticalElement.height  =  m_verticalThumb.spaceHeight * m_maskHeight / (m_maskHeight + m_verticalRange.maximum)
			m_verticalElement.y       =  (m_verticalThumb.spaceHeight - m_verticalElement.height) * m_verticalRange.ratio
		}
	}
	
	
	ns_despair var m_horizontalThumb:Fusion, m_verticalThumb:Fusion
	
	ns_despair var m_horizontalElement:NineScalePuppet, m_verticalElement:NineScalePuppet
	
	ns_despair var m_horizontalRange:RangeProperty, m_verticalRange:RangeProperty
	
	ns_despair var m_target:IComponent
	
	ns_despair var m_targetRect:Rectangle, m_scrollRect:Rectangle
	
	ns_despair var m_maskWidth:Number, m_maskHeight:Number
	
	ns_despair var m_startX:Number, m_startY:Number, m_oldX:Number, m_oldY:Number
	
	ns_despair var m_scrolling:Boolean, m_isStopPropagation:Boolean, m_locked:Boolean
	
	ns_despair var m_boundary:Number = 4
}
}